#include <stdio.h>

#define min(a,b) ((a)<(b))?(a):(b)
unsigned str_max_len=0;
char *str_max=0;

int __stdcall new_maxstr(char* s/*ESI*/,unsigned len){
	s-=len+1;//now s is common string
		str_max=s;
		return str_max_len=len;
}

void subsearch(char* T/*ext*/,unsigned Tl,char* P/*attern*/,unsigned Pl){
	unsigned i;
	
	for(i=0;i<Tl-str_max_len && Pl>str_max_len;i++){
	unsigned len=min(Tl-i,Pl);
		_asm{
		mov ECX,len
		mov EAX,T
		mov EBX,i
		lea ESI,[EAX+EBX]
		mov EDI,P
		mov EBX,str_max_len//EBX will be str_max_len
		mov EDX,ECX//EDX will be ECX val. before cmps
		dec EDX
equals:
		cld
		repe cmpsb
		jnz not_last//or last not equals
		inc EDX //mean it end of string and last characters equals. 
		inc ESI
	not_last:
		sub EDX,ECX
		cmp EBX,EDX
	jae not_equals
		push ECX
		push EDX
		push ESI
	call new_maxstr
		pop ECX
		cmp EAX,EBX//assume EBX,ESI,EDI were saved
	jbe not_equals
		cmp ECX,EAX
	jbe to_break
		mov EBX,EAX
not_equals:
		test ECX,ECX
	jz to_break
		cld
		repne cmpsb
		test ECX,ECX
	jz to_break
		mov EDX,ECX
	jmp equals
to_break:
#ifdef _DEBUG
		push Tl
		push T
		dec ESI //if last characters equals its OK
		push ESI
		call pr_assert
		push Pl
		push P
		push EDI
		call pr_assert
		jmp to_end
pr_assert://catches out of bounds
		mov EAX,[ESP+4]
		sub EAX,[ESP+8]
		sub [ESP+12],EAX
		jnc OK
		xor EAX,EAX
		mov [EAX],EBX//throw
OK:		ret 12
to_end:
#endif
		}
	}
}

void search(char **DNA,unsigned DNAlen[]){
	subsearch(DNA[0],DNAlen[0],DNA[1],DNAlen[1]);
	subsearch(DNA[1],DNAlen[1],DNA[0],DNAlen[0]);
	if(!str_max){
		printf("nothing found");
		return;
	}
	str_max[str_max_len]=0;
	printf("length:%u\tfound:\n%s\n",str_max_len,str_max);
}
